package com.qing.springbootinit.manager;
import com.qing.springbootinit.common.ErrorCode;
import com.qing.springbootinit.constant.ChatConstant;
import com.qing.springbootinit.exception.BusinessException;
import com.qing.springbootinit.model.entity.ChatMessages;
import com.qing.springbootinit.model.enums.ChatMessageEnum;
import com.qing.springbootinit.utils.EnumReflectionUtils;
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
import com.tencentcloudapi.lkeap.v20240522.models.ChatCompletionsResponse;
import io.github.briqt.spark4j.SparkClient;
import io.github.briqt.spark4j.constant.SparkApiVersion;
import io.github.briqt.spark4j.model.SparkMessage;
import io.github.briqt.spark4j.model.request.SparkRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;



/**
 * AI Manger
 *
 * @author <a href="https://github.com/qingfengzy">qingfengzy</a>
 */
@Slf4j
@Component
public class AiManager {

    @Resource
    private SparkClient sparkClient;

    @PostConstruct
    public void init(){
        try {
            // 修改 V1_5 的版本信息
            EnumReflectionUtils.setEnumField(SparkApiVersion.V1_5, "version", "v1.1");
            EnumReflectionUtils.setEnumField(SparkApiVersion.V1_5, "url", "https://spark-api.xf-yun.com/v1.1/chat");
            EnumReflectionUtils.setEnumField(SparkApiVersion.V1_5, "domain", "lite");
        } catch (Exception e) {
            log.error("尝试修改枚举字段异常：", e);
        }
    }

    /**
     * 向 AI 发送请求
     *
     * @param isNeedTemplate 是否使用模板，进行 AI 生成； true 使用 、false 不使用 ，false 的情况是只想用 AI 不只是生成前端代码
     * @param content        内容
     *                       分析需求：
     *                       分析网站用户的增长情况
     *                       原始数据：
     *                       日期,用户数
     *                       1号,10
     *                       2号,20
     *                       3号,30
     * @return AI 返回的内容
     * '【【【【'
     * <p>
     * '【【【【'
     */
    public String doChat(boolean isNeedTemplate,String content){
        List<SparkMessage> messages = new ArrayList<>();
        if(isNeedTemplate){
            // AI 生成问题的预设条件
            String predefinedInformation = "请严格按照下面的输出格式生成结果，且不得添加任何多余内容（例如无关文字、注释、代码块标记或反引号）：\n" +
                    "\n" +
                    "'【【【【'" +
                    "{ 生成 Echarts V5 的 option 配置对象 JSON 代码，要求为合法 JSON 格式且不含任何额外内容（如注释或多余字符） } '【【【【' 结论： {\n" +
                    "提供对数据的详细分析结论，内容应尽可能准确、详细，不允许添加其他无关文字或注释 }\n" +
                    "\n" +
                    "示例： 输入： 分析需求： 分析网站用户增长情况，请使用柱状图展示 原始数据： 日期,用户数 1号,10 2号,20 3号,30\n" +
                    "\n" +
                    "期望输出： '【【【【' { \"title\": { \"text\": \"分析网站用户增长情况\" }, \"xAxis\": { \"type\": \"category\", \"data\": [\"1号\", \"2号\", \"3号\"] }, \"yAxis\": { \"type\": \"value\" }, \"series\": [ { \"name\": \"用户数\", \"type\": \"bar\", \"data\": [10, 20, 30] } ] } '【【【【' 结论： 从数据看，网站用户数由1号的10人增长到2号的20人，再到3号的30人，呈现出明显的上升趋势。这表明在这段时间内网站用户吸引力增强，可能与推广活动、内容更新或其他外部因素有关。";
//            String predefinedInformation = "请严格按照下面的输出格式生成结果，且不得添加任何多余内容（例如无关文字、注释、代码块标记或反引号）：\n" +
//                    "\n" +
//                    "【【【【【" +
//                    "{ 生成 Echarts V5 的 option 配置对象 JSON 代码，要求为合法 JSON 格式且不含任何额外内容（如注释或多余字符） } '【【【【' 结论： {\n" +
//                    "提供对数据的详细分析结论，内容应尽可能准确、详细，不允许添加其他无关文字或注释 }\n" +
//                    "\n" +
//                    "示例： 输入： 分析需求： 分析网站用户增长情况，请使用柱状图展示 原始数据： 日期,用户数 1号,10 2号,20 3号,30\n" +
//                    "\n" +
//                    "期望输出： 【【【【【 { \"title\": { \"text\": \"分析网站用户增长情况\" }, \"xAxis\": { \"type\": \"category\", \"data\": [\"1号\", \"2号\", \"3号\"] }, \"yAxis\": { \"type\": \"value\" }, \"series\": [ { \"name\": \"用户数\", \"type\": \"bar\", \"data\": [10, 20, 30] } ] } '【【【【' 结论： 从数据看，网站用户数由1号的10人增长到2号的20人，再到3号的30人，呈现出明显的上升趋势。这表明在这段时间内网站用户吸引力增强，可能与推广活动、内容更新或其他外部因素有关。";
            messages.add(SparkMessage.systemContent(predefinedInformation+"\n"+ "----------------------------------"));
        }
        messages.add(SparkMessage.userContent(content));
//        构造请求
        SparkRequest sparkRequest = SparkRequest.builder()
//                消息列表
                .messages(messages)
        // 模型回答的tokens的最大长度,非必传,取值为[1,4096],默认为2048
                .maxTokens(2048)
        // 核采样阈值。用于决定结果随机性,取值越高随机性越强即相同的问题得到的不同答案的可能性越高 非必传,取值为[0,1],默认为0.5
                .temperature(0.6)
        // 指定请求版本
                .apiVersion(SparkApiVersion.V4_0)
                .build();
        // 同步调用
        String responseContent = sparkClient.chatSync(sparkRequest).getContent().trim();
//        去除一些空格
        if(!isNeedTemplate){
            return  responseContent;
        }
        log.info("星火AI返回的结果{}",responseContent);
        AtomicInteger atomicInteger = new AtomicInteger();
        while (responseContent.split("'【【【【'").length<3){
//        while (responseContent.split("【【【【【").length<3){
            responseContent = sparkClient.chatSync(sparkRequest).getContent().trim();
            if(atomicInteger.incrementAndGet()>=4){
                throw new BusinessException(ErrorCode.SYSTEM_ERROR,"星火AI生成失败");
            }
        }
        return responseContent;
    }
    /**
     * 调用AI聊天（适配星火Spark模型）
     * @param messages 历史聊天消息列表（包含用户/系统消息）
     * @return AI回复内容
     * @author <a href="https://github.com/qingfengzy">qingfengzy</a>
     */
    public String doChatByAI(List<ChatMessages> messages) {
        // 输入验证
        if (messages == null || messages.isEmpty()) {
            log.error("调用AI聊天时消息列表为空");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "消息列表不能为空");
        }

        String systemPrompt = ChatConstant.SYSTEM_PROMPT;
        try {
            // 1. 转换历史消息为星火模型要求的SparkMessage格式
            List<SparkMessage> sparkMessages = new ArrayList<>();

            // 先添加系统提示消息（确保在最前面）
            sparkMessages.add(SparkMessage.systemContent(systemPrompt));

            // 2. 转换用户/AI历史消息（跳过已有的系统消息，避免重复）
            for (ChatMessages msg : messages) {
                String sender = String.valueOf( msg.getSender());
                String content = msg.getContent();
                if (content == null || content.trim().isEmpty()) {
                    continue; // 跳过空消息
                }
                // 根据发送者角色映射为星火模型的角色（system/user/assistant）
                SparkMessage sparkMsg;
                if (ChatMessageEnum.SYSTEM.getValue().equals(sender)) {
                    // 系统消息已在最前面添加，这里不再重复
                    continue;
                } else if (ChatMessageEnum.USER.getValue().equals(sender)) {
                    sparkMsg = SparkMessage.userContent(content);
                } else if (ChatMessageEnum.AI.getValue().equals(sender)) {
                    sparkMsg = SparkMessage.assistantContent(content);
                } else {
                    log.warn("未知消息发送者: {}", sender);
                    continue; // 忽略未知角色消息
                }
                sparkMessages.add(sparkMsg);
            }

            // 3. 构建星火模型请求参数
            SparkRequest sparkRequest = SparkRequest.builder()
                    .messages(sparkMessages) // 消息列表（系统消息+历史消息）
                    .maxTokens(2048) // 最大生成token数
                    .temperature(0.6) // 随机性（0-1，越高越随机）
                    .apiVersion(SparkApiVersion.V4_0) // 使用配置的模型版本（根据实际模型选择）
                    .build();

            // 4. 同步调用星火模型
            String aiResponse = sparkClient.chatSync(sparkRequest).getContent().trim();

            // 5. 验证返回结果
            if (aiResponse == null || aiResponse.isEmpty()) {
                log.error("星火AI返回空内容");
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "AI未返回有效内容");
            }

            log.info("星火AI聊天调用成功，回复长度: {}", aiResponse.length());
            return aiResponse;

        } catch (Exception e) {
            log.error("星火AI聊天调用失败", e);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "AI聊天调用异常: " + e.getMessage());
        }
    }
}
